Delete an Object

How can i be sure that a dxl script delete an object  in a module where i have the full permission and it's open in edit mode?

The attached script fail if i have an object with children. It deletes all children, all the links but It doesn't delete the father object and it returns "object has descendants".

 

 

p.s.

can you tell me the tag for inserting the code in a post?

 


bungle_77 - Mon Jun 17 09:46:00 EDT 2013

Re: Delete an Object
HazelWoodcock - Mon Jun 17 10:36:20 EDT 2013

Francesco,

I can't answer the DXL question, but to put code in a post, use the blockquote formatting - about half way along the second row of buttons, just after indent and outdent.  I will post your script below.

    Project p_dest=project "/XXX"
string DeleteSingleRequirement(Object o, bool bHard) {
    Link l
    Object oc
    string s
    // delete the children
    for oc in o do {
        s=DeleteSingleRequirement(oc,bHard)
    }
    //delete the outcoming links
    for l in o->"*" do {
        delete l
    }
    flushDeletions()
    s=canDelete(o)
    if (s=="") {
        if (bHard) {
            hardDelete(o)
        } else {
            softDelete(o)
        }
    } else {
        // delete the incoming links
        LinkRef lref
        Object o_objSource
        ModName_ srcModRef
        for lref in o<-"*" do {        
            srcModRef = source lref
            if (!(open srcModRef)) {
                edit(fullName(srcModRef), false)
            }
        }
        for l in o<-"*" do {
            delete l
        }
        flushDeletions()
        s=canDelete(o)
        if (s=="") {
            if (bHard) {
                hardDelete(o)
            } else {
                softDelete(o)
            }
        }         
        
    }
    flushDeletions()
    return s
    
}

Object o1 = current
string res=DeleteSingleRequirement (o1,true)
print res
 

 

Re: Delete an Object
GregM_dxler - Mon Jun 17 10:49:37 EDT 2013

Hello,

The first thing I noticed is that the source module of the incoming links needs to be saved in order for the link to actually be removed.  Not sure if this has anything to do with the object has descendents though.

Greg

Re: Delete an Object
bungle_77 - Mon Jun 17 11:04:58 EDT 2013

GregM_dxler - Mon Jun 17 10:49:37 EDT 2013

Hello,

The first thing I noticed is that the source module of the incoming links needs to be saved in order for the link to actually be removed.  Not sure if this has anything to do with the object has descendents though.

Greg

it's not that the problem, i can delete an object even without  saveing the source module

 

thanks Hazel

Re: Delete an Object
bungle_77 - Tue Jun 18 04:20:06 EDT 2013

bungle_77 - Mon Jun 17 11:04:58 EDT 2013

it's not that the problem, i can delete an object even without  saveing the source module

 

thanks Hazel

i tried this script on an Object A with two children A1 and A2. with an outcoming link from A to A1 and A2. and each of these 3 objects has in and out links to other objects

Re: Delete an Object
bungle_77 - Tue Jun 18 04:58:19 EDT 2013

bungle_77 - Tue Jun 18 04:20:06 EDT 2013

i tried this script on an Object A with two children A1 and A2. with an outcoming link from A to A1 and A2. and each of these 3 objects has in and out links to other objects

i found out the error. I made the flushdeletion inside the loop     "for oc in o do". I should call this function in a recursive way till it returns "object has descendants"

Re: Delete an Object
bungle_77 - Tue Jun 18 05:52:12 EDT 2013

bungle_77 - Tue Jun 18 04:58:19 EDT 2013

i found out the error. I made the flushdeletion inside the loop     "for oc in o do". I should call this function in a recursive way till it returns "object has descendants"

i thought i solved the problem, but i still have it :-(

here the new code

void deleteObjLinks (Object o) {
    Link l
    Object oc

    // delete the children
    for oc in o do {
        deleteObjLinks(oc)
    }
    //delete the outcoming links
    for l in o->"*" do {
        delete l
    }


    // delete the incoming links
    LinkRef lref
    Object o_objSource
    ModName_ srcModRef
    for lref in o<-"*" do {        
        srcModRef = source lref
        if (!(open srcModRef)) {
            edit(fullName(srcModRef), false)
        }
    }
    for l in o<-"*" do {
        delete l
    }
    flushDeletions()
    
}

string DeleteObjectWithChildren    (Object o, bool bHard) {

    Object oc
    string s
    // delete the children
    for oc in o do {
        s=DeleteObjectWithChildren(oc,bHard)
    }
    flushDeletions()
    s=canDelete(o)
    if (s=="") {
        if (bHard) {
            hardDelete(o)
        } else {
            softDelete(o)
        }
    }
    return s

}
    
string DeleteSingleRequirement(Object o, bool bHard) {
    string s
    deleteObjLinks(o)
    flushDeletions()
    s=DeleteObjectWithChildren(o,bHard)
    flushDeletions()
    return s
    
}

Object o1 = current
string res=DeleteSingleRequirement (o1,true)
print res
 

Re: Delete an Object
bungle_77 - Tue Jun 18 06:18:14 EDT 2013

bungle_77 - Tue Jun 18 05:52:12 EDT 2013

i thought i solved the problem, but i still have it :-(

here the new code

void deleteObjLinks (Object o) {
    Link l
    Object oc

    // delete the children
    for oc in o do {
        deleteObjLinks(oc)
    }
    //delete the outcoming links
    for l in o->"*" do {
        delete l
    }


    // delete the incoming links
    LinkRef lref
    Object o_objSource
    ModName_ srcModRef
    for lref in o<-"*" do {        
        srcModRef = source lref
        if (!(open srcModRef)) {
            edit(fullName(srcModRef), false)
        }
    }
    for l in o<-"*" do {
        delete l
    }
    flushDeletions()
    
}

string DeleteObjectWithChildren    (Object o, bool bHard) {

    Object oc
    string s
    // delete the children
    for oc in o do {
        s=DeleteObjectWithChildren(oc,bHard)
    }
    flushDeletions()
    s=canDelete(o)
    if (s=="") {
        if (bHard) {
            hardDelete(o)
        } else {
            softDelete(o)
        }
    }
    return s

}
    
string DeleteSingleRequirement(Object o, bool bHard) {
    string s
    deleteObjLinks(o)
    flushDeletions()
    s=DeleteObjectWithChildren(o,bHard)
    flushDeletions()
    return s
    
}

Object o1 = current
string res=DeleteSingleRequirement (o1,true)
print res
 

i restricted the problem i just created a requirement with three children and no links and this simple code:

string DeleteObjectWithChildren    (Object o) {
    Object oc

    string s
    // delete the children
    for oc in o do {
        hardDelete(oc)
    }
flushDeletions()
    s=canDelete(o)
    if (s=="") {

            hardDelete(o)

    }
    print s "\n"
return s
}
Object o=current
DeleteObjectWithChildren(o)

i got the same error

Re: Delete an Object
GregM_dxler - Tue Jun 18 09:57:25 EDT 2013

bungle_77 - Tue Jun 18 06:18:14 EDT 2013

i restricted the problem i just created a requirement with three children and no links and this simple code:

string DeleteObjectWithChildren    (Object o) {
    Object oc

    string s
    // delete the children
    for oc in o do {
        hardDelete(oc)
    }
flushDeletions()
    s=canDelete(o)
    if (s=="") {

            hardDelete(o)

    }
    print s "\n"
return s
}
Object o=current
DeleteObjectWithChildren(o)

i got the same error

Your latest code works for me in that an object with children all get deleted.  It doesn't work if the children have children but throws a dxl error with the message object has descendents.  This makes sense since the child has a child.  Change the loop to the following:

for oc in o do {

if (null first oc) hardDelete(oc)

else DeleteObjectWithChildren(oc)

}

This will recursively go through each level, deleting the children's children.

Looks like softDelete(o) will delete the children but not the parent.  Not sure why this is.  The dxl help says the object is marked for deletion but not actually deleted.  It doesn't look like it is marked for deletion to me, but then I didn't try to purge it afterwards either.

Good luck,

Greg

Re: Delete an Object
bungle_77 - Tue Jun 18 10:49:31 EDT 2013

GregM_dxler - Tue Jun 18 09:57:25 EDT 2013

Your latest code works for me in that an object with children all get deleted.  It doesn't work if the children have children but throws a dxl error with the message object has descendents.  This makes sense since the child has a child.  Change the loop to the following:

for oc in o do {

if (null first oc) hardDelete(oc)

else DeleteObjectWithChildren(oc)

}

This will recursively go through each level, deleting the children's children.

Looks like softDelete(o) will delete the children but not the parent.  Not sure why this is.  The dxl help says the object is marked for deletion but not actually deleted.  It doesn't look like it is marked for deletion to me, but then I didn't try to purge it afterwards either.

Good luck,

Greg

i solved by this way:

 

void deleteObjLinks (Object o) {
    Link l
    Object oc

    // delete the children
    for oc in o do {
        deleteObjLinks(oc)
    }
    //delete the outcoming links
    for l in o->"*" do {
        delete l
    }


    // delete the incoming links
    LinkRef lref
    Object o_objSource
    ModName_ srcModRef
    for lref in o<-"*" do {        
        srcModRef = source lref
        if (!(open srcModRef)) {
            edit(fullName(srcModRef), false)
        }
    }
    for l in o<-"*" do {
        delete l
    }
    flushDeletions()
    
}

    
string DeleteSingleRequirement(Object o) {
    string s
    deleteObjLinks(o)
    flushDeletions()
    softDelete (o)
    flushDeletions()
    return s
    
}

Object o1=current

Module m= current

DeleteSingleRequirement o

purgeObjects_(m)

 

i just made a softdeletion of the father and then i purge all the objects of the module

Re: Delete an Object
llandale - Tue Jun 18 13:49:17 EDT 2013

GregM_dxler - Mon Jun 17 10:49:37 EDT 2013

Hello,

The first thing I noticed is that the source module of the incoming links needs to be saved in order for the link to actually be removed.  Not sure if this has anything to do with the object has descendents though.

Greg

Not quite.  "flushDeletions" needs to be executed before the target does not see the link and allows it to be deleted.  Try this:

  • Edit source
  • Edit target
  • delete source link
  • flushDeletions
  • delete target objects
  • save and close target module
  • close, but do NOT save source module.
  • Open target module.
  • Notice the deleted object has an incoming link

-Louie

Re: Delete an Object
llandale - Tue Jun 18 14:15:07 EDT 2013

Not quite following, but IIRC the following are true and must be considered by the script.

  • If you delete an object you also delete all it's descendants.
  • You cannot delete an object with incoming links
  • By convention, you should not delete an object with outgoing links.
  • The GUI "delete" button interates through the descendant objects first
  • While in the GUI you can "purge" (aka "hardDelete") only a deleted object; in DXL you can only "hardDelete" an undeleted object.  In order to "hardDelete" a deleted object in DXL, you first have to "undelete" it. 

Your script I think needs to be recursive; looking like this

  • void DeleteMe(Object o)
  • {  if (null o) return
  •    if (isDeleted(o)) then whatever
  •    for each child of o; DeleteMe(oChild)  // RECURSION
  •    deleting outgoing links
  •    delete incoming links
  •    flushDeletions
  •    delete(o)
  •    flushDeletions
  • }
  • Somewhere deal with saving all modules sourcing links that you deleted.

I think I would tend to write separate "delete" and "purge" functions, partly because they are diffferent and partly to prevent accidental destruction, when "false" was intended but "true" entered.  Not that I've ever done that...

-Louie

Not sure how I did it years ago, but I did manage to get a module with undeleted object with a deleted parent.  So some scripts need to deal with that possibility.